#define BLINKER_WIFI
#include <Blinker.h>
#include <IRremoteESP8266.h>
#include <IRsend.h>
#include <DHT.h>
#include "MideaRawCodes.h"

char auth[] = "68a0e8b0a2f1"; //BlinkerAPP上的设备密钥
char ssid[] = "DXR 7400"; //WIFI账号
char pswd[] = "zxcvbnm.."; //WIFI密码

#define DHTPIN D1      //温湿度传感器引脚
#define DHTTYPE DHT11  // DHT 11
#define IRSENDPIN D2   //红外发射引脚(空调)
#define LED1PIN D5     //LED1(寝室灯)引脚
#define LED2PIN D6     //LED2(寝室灯)引脚
#define LED3PIN D7     //LED3(卫生间灯)引脚
#define LED4PIN D8     //LED4(阳台灯)引脚


// 新建组件对象
BlinkerButton LEDBtn1("btn-led1");//寝室灯
BlinkerButton LEDBtn3("btn-led3");//控制卫生间灯
BlinkerButton LEDBtn4("btn-led4");//控制阳台灯
BlinkerButton ColdAirBtn("btn-coldAir");//控制空调
BlinkerButton adjustTBtn("btn-adjustT");//语音调温
BlinkerSlider ColdAirSli("slider-coldAir");//调节空调温度
BlinkerNumber TEMP("num-temp");//温度
BlinkerNumber HUMI("num-humi");//湿度

DHT dht(DHTPIN, DHTTYPE); //DHT11温湿度对象
float tempNum = 0, humiNum = 0; //温湿度值

IRsend irsend(IRSENDPIN); //红外发射对象
int currentDeg = 23; //监控空调度数  初始化为23度
boolean coldAirState = false; //空调状态

//选择空调的冷气度数
void selectColdAir(int value) {
  // 发射对应的红外信号
  switch (value) {
    case 0 : irsend.sendRaw(_CLOSE, RAWLEN, 38);  return; //value为0时 不需要存入currentDeg 因此直接return
    case 17: irsend.sendRaw(DEG_17, RAWLEN, 38);  break;
    case 18: irsend.sendRaw(DEG_18, RAWLEN, 38);  break;
    case 19: irsend.sendRaw(DEG_19, RAWLEN, 38);  break;
    case 20: irsend.sendRaw(DEG_20, RAWLEN, 38);  break;
    case 21: irsend.sendRaw(DEG_21, RAWLEN, 38);  break;
    case 22: irsend.sendRaw(DEG_22, RAWLEN, 38);  break;
    case 23: irsend.sendRaw(DEG_23, RAWLEN, 38);  break;
    case 24: irsend.sendRaw(DEG_24, RAWLEN, 38);  break;
    case 25: irsend.sendRaw(DEG_25, RAWLEN, 38);  break;
    case 26: irsend.sendRaw(DEG_26, RAWLEN, 38);  break;
    case 27: irsend.sendRaw(DEG_27, RAWLEN, 38);  break;
    case 28: irsend.sendRaw(DEG_28, RAWLEN, 38);  break;
    case 29: irsend.sendRaw(DEG_29, RAWLEN, 38);  break;
    case 30: irsend.sendRaw(DEG_30, RAWLEN, 38);  break;
    default: BLINKER_LOG("get slider value: ", value); return;
  }

  currentDeg = value;
}

//滑块控制空调度数回调函数
void slider_coldAir(int32_t value)
{
  //  BLINKER_LOG("get slider value: ", value);
  if (coldAirState == true) {
    selectColdAir(value);
  }
}

// 按键控制空调的回调函数
void button_coldAir(const String & state)
{
  //  BLINKER_LOG("get button state: ", state);
  if (state == "on") {
    ColdAirBtn.print("on");
    coldAirState = true;
    selectColdAir(currentDeg); //选择空调度数
  } else {
    ColdAirBtn.print("off");
    coldAirState = false;
    selectColdAir(0); //选择空调度数0 代表关闭空调
  }
}

//按键语音调节空调温度回调函数
void button_adjustT(const String & state) {
  if (coldAirState == true) {
    if (state == "on") {
      currentDeg += 2;
      adjustTBtn.print("on");
    } else if (state == "off") {
      currentDeg -= 2;
      adjustTBtn.print("off");
    } else if (state == "tap") {

      if (tempNum >= 25 && tempNum <= 27) {
        currentDeg = 27;
      } else if (tempNum >= 28 && tempNum <= 30) {
        currentDeg = 25;
      } else if (tempNum >= 31 && tempNum <= 32) {
        currentDeg = 22;
      } else if (tempNum >= 33 && tempNum <= 35) {
        currentDeg = 19;
      } else {
        currentDeg = 17;
      }
      adjustTBtn.print("tap");
    }
    //防止调节的度数超出范围
    if (currentDeg < 17) {
      currentDeg = 17;
    }
    if (currentDeg > 30) {
      currentDeg = 30;
    }
    selectColdAir(currentDeg);
  }
}

// 按键控制led1的回调函数
void button_led1(const String & state)
{
  //  BLINKER_LOG("get button state: ", state);
  if (state == "on") {
    digitalWrite(LED1PIN, HIGH);
    digitalWrite(LED2PIN, HIGH);
    LEDBtn1.print("on");
  } else {
    digitalWrite(LED1PIN, LOW);
    digitalWrite(LED2PIN, LOW);
    LEDBtn1.print("off");
  }
}

// 按键控制led3的回调函数
void button_led3(const String & state)
{
  //  BLINKER_LOG("get button state: ", state);
  if (state == "on") {
    digitalWrite(LED3PIN, HIGH);
    LEDBtn3.print("on");
  } else {
    digitalWrite(LED3PIN, LOW);
    LEDBtn3.print("off");
  }
}

// 按键控制led4的回调函数
void button_led4(const String & state)
{
  //  BLINKER_LOG("get button state: ", state);
  if (state == "on") {
    digitalWrite(LED4PIN, HIGH);
    LEDBtn4.print("on");
  } else {
    digitalWrite(LED4PIN, LOW);
    LEDBtn4.print("off");
  }
}

// 心跳包函数 没59秒更新一次APP的部分UI状态
void heartbeat()
{
  TEMP.print(tempNum);
  HUMI.print(humiNum);
  ColdAirBtn.print(coldAirState ? "on" : "off");
  ColdAirSli.print(currentDeg);
}

//历史数据存储
void dataStorage()
{
  Blinker.dataStorage("num-temp", tempNum);
  Blinker.dataStorage("num-humi", humiNum);
}

void setup()
{
  // 初始化串口
  Serial.begin(115200);
  //  BLINKER_DEBUG.stream(Serial);
  //  BLINKER_DEBUG.debugAll();

  // 初始化有LED的IO
  pinMode(LED1PIN, OUTPUT);
  pinMode(LED2PIN, OUTPUT);
  pinMode(LED3PIN, OUTPUT);
  pinMode(LED4PIN, OUTPUT);

  // 初始化blinker
  Blinker.begin(auth, ssid, pswd);
  LEDBtn1.attach(button_led1); //注册一个按键控制led1
  LEDBtn3.attach(button_led3); //注册一个按键控制led3
  LEDBtn4.attach(button_led4); //注册一个按键控制led4
  ColdAirBtn.attach(button_coldAir); //注册一个按键控制空调
  adjustTBtn.attach(button_adjustT); //注册一个按键语音调节空调温度
  ColdAirSli.attach(slider_coldAir); //注册一个控制空调度数的滑块组件
  Blinker.attachHeartbeat(heartbeat); //注册一个心跳包
  Blinker.attachDataStorage(dataStorage); //开启历史数据存储

  irsend.begin(); //红外发射
  dht.begin(); //温湿度
}

void loop() {
  Blinker.run();
  float t = dht.readTemperature();
  float h = dht.readHumidity();

  if (isnan(t) || isnan(h))
  {
    BLINKER_LOG("无法读取到温湿度数据");
  }
  else
  {
    BLINKER_LOG("Temperature: ", t, " *C");
    BLINKER_LOG("Humidity: ", h, " %");
    tempNum = t;
    humiNum = h;
  }
  Blinker.delay(2000);
}
